package tarantula.instrumenter;

import java.util.LinkedList;
import java.util.List;

import plume.Option;
import plume.Options;
import soot.Pack;
import soot.PackManager;
import soot.Scene;
import soot.SootClass;
import soot.Transform;
import tarantula.util.Globals;

public class JUnitInstrumentMain {
	@Option("The input dir of all JUnit classes after transformation")
	public static String junit_input_dir = null;

	@Option("The output dir for all JUnit classes after transformation")
	public static String junit_output_dir = null;
	
	@Option("JUnit output format, the same as Soot's")
	public static String junit_output_format = "jimple"; //or "J"
	
	public static void main(String[] args) {
//		args = new String[]{"--junit_input_dir", "xxxx",
//				            "--junit_output_dir", "yyy"};
		String extraClassPath = "G:/72_Simplify/workspace_simplify/TarantulaJ/bin/"; 
				// "G:/72_Simplify/workspace_simplify/apache-commons-collections-2.0/bin/";
		String includePkg = "org.apache.";
		
		//parsing the argument
		parse_check_and_set_args(args);
		
		System.out.println("input: " + junit_input_dir + ",  output: " + junit_output_dir);
		
		/* add a phase to transformer pack by call Pack.add */
		Pack jtp = PackManager.v().getPack("jtp");
		jtp.add(new Transform("jtp.junitinstrumenter",
				new JUnitTestInstrumenter()));
		
		//call the instrumenter
		List<String> sootArgs = new LinkedList<String>();
		
		sootArgs.add("-prepend-classpath");
		sootArgs.add("-keep-line-number");
		sootArgs.add("-soot-class-path");
		sootArgs.add("." + Globals.pathSep + junit_input_dir +
				Globals.pathSep + Globals.getClassPath() +
				Globals.pathSep + extraClassPath
		);
		System.out.println("." + Globals.pathSep + junit_input_dir + Globals.pathSep + Globals.getClassPath());
		sootArgs.add("-output-format");
		sootArgs.add(junit_output_format);
		if(includePkg != null){
			sootArgs.add("-i");
			sootArgs.add(includePkg);
		}
		sootArgs.add("-process-dir");
		sootArgs.add(junit_input_dir);
		sootArgs.add("-output-dir");
		sootArgs.add(junit_output_dir);
		
		Scene.v().addBasicClass("tarantula.instrumenter.Tracer", SootClass.SIGNATURES);
		soot.Main.main(sootArgs.toArray(new String[0]));
	}
	
	
	private static void parse_check_and_set_args(String[] args) {
		//process the arguments
		Options options = new Options("Tarantua Instrumenting JUnit: ", JUnitInstrumentMain.class);
		String[] file_args = options.parse_or_usage(args);
		if(file_args.length != 0) {
			for(String errorMsg : file_args) {
				System.out.println(errorMsg);
				System.exit(1);
			}
		}
		
		if(JUnitInstrumentMain.junit_input_dir == null) {
			System.out.println("The input dir of all JUnit classes to be transformed can not be null!");
			System.out.println();
			options.print_usage();
			System.exit(1);
		}
		
		if(JUnitInstrumentMain.junit_output_dir == null) {
			System.out.println("The output dir for all transformed classes can not be null!");
			System.out.println();
			options.print_usage();
			System.exit(1);
		}
	}
}
